// PLC持续监控方式对比测试

// 模拟PLC服务
class MockPLCService {
  constructor() {
    this.variables = {
      'DB1,W0.0': 25,    // 温度
      'DB1,W2.0': 60,    // 湿度
      'DB1,W4.0': 1,     // 货架状态
      'DB1,W6.0': 1      // 系统状态
    };
    
    // 定时更新模拟变量值
    this.updateInterval = setInterval(() => {
      // 随机更新温度值
      this.variables['DB1,W0.0'] = 20 + Math.random() * 15;
      
      // 随机更新湿度值
      this.variables['DB1,W2.0'] = 50 + Math.random() * 30;
      
      // 随机切换货架状态
      if (Math.random() > 0.7) {
        this.variables['DB1,W4.0'] = this.variables['DB1,W4.0'] === 0 ? 1 : 0;
      }
    }, 2000);
  }
  
  // 模拟直接读取变量
  async directReadVariables(variables) {
    // 模拟网络延迟
    await new Promise(resolve => setTimeout(resolve, 10 + Math.random() * 20));
    
    const result = {};
    variables.forEach(variable => {
      result[variable] = this.variables[variable];
    });
    return result;
  }
  
  // 模拟通过队列服务读取变量
  async queueReadVariables(variables) {
    // 模拟队列服务延迟
    await new Promise(resolve => setTimeout(resolve, 50 + Math.random() * 100));
    
    const result = {};
    variables.forEach(variable => {
      result[variable] = this.variables[variable];
    });
    return result;
  }
  
  // 模拟写入变量
  async writeVariable(variable, value) {
    this.variables[variable] = value;
    return { success: true, variable, value };
  }
  
  // 停止模拟更新
  stop() {
    if (this.updateInterval) {
      clearInterval(this.updateInterval);
    }
  }
}

// 模拟PLC服务实例
const mockPLC = new MockPLCService();

// PLC监控服务 - 直接读取模式
class DirectPLCMonitoringService {
  constructor() {
    this.monitoringVariables = new Map();
    this.monitoringInterval = null;
    this.monitoringIntervalTime = 1000;
  }
  
  // 启动监控 - 直接读取
  startMonitoring(variables, callback, intervalTime = 1000) {
    this.stopMonitoring();
    this.monitoringIntervalTime = intervalTime;
    
    variables.forEach(variable => {
      this.monitoringVariables.set(variable, { 
        lastValue: null, 
        callback: callback,
        errorCount: 0
      });
    });
    
    this._runMonitoringLoop();
    console.log(`✅ 启动PLC变量监控(直接读取)，监控 ${variables.length} 个变量，间隔 ${intervalTime}ms`);
  }
  
  // 停止监控
  stopMonitoring() {
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }
    
    this.monitoringVariables.clear();
    console.log('🛑 停止PLC变量监控(直接读取)');
  }
  
  // 运行监控循环 - 直接读取
  async _runMonitoringLoop() {
    this.monitoringInterval = setInterval(async () => {
      if (this.monitoringVariables.size === 0) return;
      
      try {
        const variables = Array.from(this.monitoringVariables.keys());
        // 直接读取PLC变量
        const values = await mockPLC.directReadVariables(variables);
        
        for (const variable of variables) {
          const variableInfo = this.monitoringVariables.get(variable);
          const newValue = values[variable];
          
          if (variableInfo.lastValue !== newValue) {
            if (variableInfo.callback) {
              try {
                variableInfo.callback(variable, newValue, variableInfo.lastValue);
              } catch (err) {
                console.error(`❌ 监控变量回调执行失败 ${variable}:`, err);
              }
            }
            
            variableInfo.lastValue = newValue;
            variableInfo.errorCount = 0;
          }
        }
      } catch (err) {
        console.error('❌ PLC监控循环执行失败(直接读取):', err);
        
        for (const [variable, info] of this.monitoringVariables.entries()) {
          info.errorCount++;
          if (info.errorCount > 5) {
            console.warn(`⚠️ 变量 ${variable} 连续错误超过阈值，从监控中移除`);
            this.monitoringVariables.delete(variable);
          }
        }
      }
    }, this.monitoringIntervalTime);
  }
}

// PLC监控服务 - 队列服务模式
class QueuePLCMonitoringService {
  constructor() {
    this.monitoringVariables = new Map();
    this.monitoringInterval = null;
    this.monitoringIntervalTime = 1000;
  }
  
  // 启动监控 - 通过队列服务读取
  startMonitoring(variables, callback, intervalTime = 1000) {
    this.stopMonitoring();
    this.monitoringIntervalTime = intervalTime;
    
    variables.forEach(variable => {
      this.monitoringVariables.set(variable, { 
        lastValue: null, 
        callback: callback,
        errorCount: 0
      });
    });
    
    this._runMonitoringLoop();
    console.log(`✅ 启动PLC变量监控(队列服务)，监控 ${variables.length} 个变量，间隔 ${intervalTime}ms`);
  }
  
  // 停止监控
  stopMonitoring() {
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }
    
    this.monitoringVariables.clear();
    console.log('🛑 停止PLC变量监控(队列服务)');
  }
  
  // 运行监控循环 - 通过队列服务读取
  async _runMonitoringLoop() {
    this.monitoringInterval = setInterval(async () => {
      if (this.monitoringVariables.size === 0) return;
      
      try {
        const variables = Array.from(this.monitoringVariables.keys());
        // 通过队列服务读取PLC变量
        const values = await mockPLC.queueReadVariables(variables);
        
        for (const variable of variables) {
          const variableInfo = this.monitoringVariables.get(variable);
          const newValue = values[variable];
          
          if (variableInfo.lastValue !== newValue) {
            if (variableInfo.callback) {
              try {
                variableInfo.callback(variable, newValue, variableInfo.lastValue);
              } catch (err) {
                console.error(`❌ 监控变量回调执行失败 ${variable}:`, err);
              }
            }
            
            variableInfo.lastValue = newValue;
            variableInfo.errorCount = 0;
          }
        }
      } catch (err) {
        console.error('❌ PLC监控循环执行失败(队列服务):', err);
        
        for (const [variable, info] of this.monitoringVariables.entries()) {
          info.errorCount++;
          if (info.errorCount > 5) {
            console.warn(`⚠️ 变量 ${variable} 连续错误超过阈值，从监控中移除`);
            this.monitoringVariables.delete(variable);
          }
        }
      }
    }, this.monitoringIntervalTime);
  }
}

// 性能测试函数
async function performanceTest() {
  console.log('🚀 开始PLC持续监控性能测试...');
  
  const testVariables = [
    'DB1,W0.0',  // 温度
    'DB1,W2.0',  // 湿度
    'DB1,W4.0',  // 货架状态
    'DB1,W6.0'   // 系统状态
  ];
  
  // 测试直接读取模式
  console.log('\n=== 测试直接读取模式 ===');
  const directMonitor = new DirectPLCMonitoringService();
  
  const directStart = Date.now();
  directMonitor.startMonitoring(testVariables, (variable, newValue, oldValue) => {
    // 简单回调，不输出日志以减少干扰
  }, 100);
  
  // 运行5秒
  await new Promise(resolve => setTimeout(resolve, 5000));
  directMonitor.stopMonitoring();
  const directEnd = Date.now();
  
  console.log(`直接读取模式运行时间: ${directEnd - directStart}ms`);
  
  // 测试队列服务模式
  console.log('\n=== 测试队列服务模式 ===');
  const queueMonitor = new QueuePLCMonitoringService();
  
  const queueStart = Date.now();
  queueMonitor.startMonitoring(testVariables, (variable, newValue, oldValue) => {
    // 简单回调，不输出日志以减少干扰
  }, 100);
  
  // 运行5秒
  await new Promise(resolve => setTimeout(resolve, 5000));
  queueMonitor.stopMonitoring();
  const queueEnd = Date.now();
  
  console.log(`队列服务模式运行时间: ${queueEnd - queueStart}ms`);
  
  // 计算性能差异
  const timeDifference = queueEnd - queueStart - (directEnd - directStart);
  console.log(`\n📊 性能对比结果:`);
  console.log(`队列服务模式比直接读取模式多消耗: ${timeDifference}ms`);
  console.log(`平均每次读取多消耗: ${timeDifference / 50}ms`);
  
  mockPLC.stop();
  console.log('✅ PLC持续监控性能测试完成');
}

// 功能对比测试
async function functionalityTest() {
  console.log('🚀 开始PLC持续监控功能对比测试...');
  
  const testVariables = [
    'DB1,W0.0',  // 温度
    'DB1,W2.0',  // 湿度
    'DB1,W4.0',  // 货架状态
    'DB1,W6.0'   // 系统状态
  ];
  
  // 直接读取模式测试
  console.log('\n=== 直接读取模式测试 ===');
  const directMonitor = new DirectPLCMonitoringService();
  
  directMonitor.startMonitoring(testVariables, (variable, newValue, oldValue) => {
    console.log(`📊 直接读取 - ${variable} 变化: ${oldValue} → ${newValue}`);
  }, 500);
  
  // 运行3秒
  await new Promise(resolve => setTimeout(resolve, 3000));
  directMonitor.stopMonitoring();
  
  // 队列服务模式测试
  console.log('\n=== 队列服务模式测试 ===');
  const queueMonitor = new QueuePLCMonitoringService();
  
  queueMonitor.startMonitoring(testVariables, (variable, newValue, oldValue) => {
    console.log(`📊 队列服务 - ${variable} 变化: ${oldValue} → ${newValue}`);
  }, 500);
  
  // 运行3秒
  await new Promise(resolve => setTimeout(resolve, 3000));
  queueMonitor.stopMonitoring();
  
  mockPLC.stop();
  console.log('✅ PLC持续监控功能对比测试完成');
}

// 运行测试
async function runTests() {
  await performanceTest();
  console.log('\n' + '='.repeat(50) + '\n');
  await functionalityTest();
}

// 如果直接运行此脚本，则执行测试
if (require.main === module) {
  runTests().catch(console.error);
}

module.exports = { 
  MockPLCService, 
  DirectPLCMonitoringService, 
  QueuePLCMonitoringService 
};